package com.magold.ut;

import org.andengine.engine.camera.Camera;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.primitive.Rectangle;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.Background;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.extension.physics.box2d.PhysicsFactory;
import org.andengine.extension.physics.box2d.PhysicsWorld;
import org.andengine.input.sensor.acceleration.AccelerationData;
import org.andengine.input.sensor.acceleration.IAccelerationListener;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.andengine.opengl.texture.region.ITiledTextureRegion;
import org.andengine.opengl.texture.region.TiledTextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;

import android.hardware.SensorManager;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.magold.physics.MagoldPhysicsConnector;

/**
 * @author Nicolas Gramlich
 * @since 18:47:08 - 19.03.2010
 */
public class BasePhysicsJointExample extends BaseExample implements IAccelerationListener {
	// ===========================================================
	// Constants
	// ===========================================================

	protected static final int CAMERA_WIDTH = 800;
	protected static final int CAMERA_HEIGHT = 480;

	// ===========================================================
	// Fields
	// ===========================================================

	private BitmapTextureAtlas mTexture;

	protected TiledTextureRegion mBoxFaceTextureRegion;
	protected TiledTextureRegion mCircleFaceTextureRegion;

	protected PhysicsWorld mPhysicsWorld;

	@Override
	public EngineOptions onCreateEngineOptions() {
		Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
		return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);
	}

	@Override
	public void onCreateResources(OnCreateResourcesCallback pCallback) {
		BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/ut/");
		mTexture = new BitmapTextureAtlas(getTextureManager(), 64, 64);
		mBoxFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mTexture, this, "face_box_tiled.png", 0, 0, 2, 1); // 64x32
		mCircleFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mTexture, this, "face_circle_tiled.png", 0, 32, 2, 1); // 64x32
		mEngine.getTextureManager().loadTexture(this.mTexture);
		
		this.enableAccelerationSensor(this);
		
		pCallback.onCreateResourcesFinished();
	}

	@Override
	public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) {
		Scene scene = new Scene();
		scene.setBackground(new Background(0, 0, 0));

		this.mPhysicsWorld = new PhysicsWorld(new Vector2(0, SensorManager.GRAVITY_EARTH), false);
		
		VertexBufferObjectManager vbom = getVertexBufferObjectManager();
		Rectangle ground = new Rectangle(0, CAMERA_HEIGHT - 2, CAMERA_WIDTH, 2, vbom);
		Rectangle roof = new Rectangle(0, 0, CAMERA_WIDTH, 2, vbom);
		Rectangle left = new Rectangle(0, 0, 2, CAMERA_HEIGHT, vbom);
		Rectangle right = new Rectangle(CAMERA_WIDTH - 2, 0, 2, CAMERA_HEIGHT, vbom);
		
		FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(0, 0.5f, 0.5f);
		PhysicsFactory.createBoxBody(this.mPhysicsWorld, ground, BodyType.StaticBody, wallFixtureDef);
		PhysicsFactory.createBoxBody(this.mPhysicsWorld, roof, BodyType.StaticBody, wallFixtureDef);
		PhysicsFactory.createBoxBody(this.mPhysicsWorld, left, BodyType.StaticBody, wallFixtureDef);
		PhysicsFactory.createBoxBody(this.mPhysicsWorld, right, BodyType.StaticBody, wallFixtureDef);

		scene.attachChild(ground);
		scene.attachChild(roof);
		scene.attachChild(left);
		scene.attachChild(right);
		
		scene.registerUpdateHandler(this.mPhysicsWorld);
		
		pOnCreateSceneCallback.onCreateSceneFinished(scene);
	}

	@Override
	public void onPopulateScene(Scene pScene, OnPopulateSceneCallback pCallback) {
		pCallback.onPopulateSceneFinished();
	}

	@Override
	public void onAccelerationAccuracyChanged(AccelerationData pAccelerationData) {
		
	}

	@Override
	public void onAccelerationChanged(AccelerationData pAccelerationData) {
		this.mPhysicsWorld.setGravity(new Vector2(pAccelerationData.getX(), pAccelerationData.getY()));
	}

	// ===========================================================
	// Methods
	// ===========================================================

	protected MagoldPhysicsConnector addFace(final float pX, final float pY, ITiledTextureRegion pBoxFaceTextureRegion, FixtureDef pDef) {
		final AnimatedSprite boxFace = new AnimatedSprite(410, 310, pBoxFaceTextureRegion, getVertexBufferObjectManager());
		final Body boxBody = PhysicsFactory.createBoxBody(mPhysicsWorld, boxFace, BodyType.DynamicBody, pDef);
		boxFace.animate(200);
		getEngine().getScene().attachChild(boxFace);
		final MagoldPhysicsConnector boxConnector = new MagoldPhysicsConnector(boxFace, boxBody);
		mPhysicsWorld.registerPhysicsConnector(boxConnector);
		
		return boxConnector;
	}


	// ===========================================================
	// Inner and Anonymous Classes
	// ===========================================================
}
